home *** CD-ROM | disk | FTP | other *** search
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Bookmark Previews extension.
- *
- * The Initial Developer of the Original Code is
- * John Marshall <JohnM555@gmail.com>.
- * Portions created by the Initial Developer are Copyright (C) 2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * John Marshall <JohnM555@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
- if (!("STATE_START" in window)){
- STATE_START = Components.interfaces.nsIWebProgressListener.STATE_START;
- STATE_STOP = Components.interfaces.nsIWebProgressListener.STATE_STOP;
- }
- var PreviewService = {
- PREVIEW_WIDTH: 600,
- timeouts: [],
- listener : null,
- bookmarks: null,
- generator : null,
- _prefs : null,
- get prefs(){
- if (!this._prefs){
- this._prefs = Components.classes["@mozilla.org/preferences-service;1"].
- getService(Components.interfaces.nsIPrefService);
- this._prefs = this._prefs.getBranch("extensions.bookmarkpreviews.");
- }
- return this._prefs;
- },
- isFF3 : false,
- /* since load is called around 7 times for some sites before it actually loads,
- just cache the last isBookmark check. isBookmark might not take long, but whatever */
- _lastCheck : {uri : {spec : null}, isBookmarked : false},
- onLoad: function() {
- var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
- .getService(Components.interfaces.nsIXULAppInfo);
- var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
- .getService(Components.interfaces.nsIVersionComparator);
- PreviewService.isFF3 = (versionChecker.compare(appInfo.version, "3.0a") >= 0);
- if (PreviewService.isFF3)
- PreviewService.bookmarks = new PreviewServiceFF3();
- else{
- /*
- Use the listener to check for redirected bookmarks.
- FF3 doesn't need this because it has a better bookmarking system.
- */
- PreviewService.bookmarks = new PreviewServiceFF2();
- PreviewService.listener = new BookmarkPreviewsProgressListener();
- PreviewService.listener.onURILoad = PreviewService.onURILoad;
- PreviewService.listener.getBrowser = PreviewService.getBrowserForURI;
- gBrowser.addProgressListener(PreviewService.listener,Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
- }
- gBrowser.addEventListener('load',PreviewService.onPageLoad,true);
- var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
- .getService(Components.interfaces.nsIVersionComparator);
- var em = Components.classes["@mozilla.org/extensions/manager;1"]
- .getService(Components.interfaces.nsIExtensionManager);
- var addon = em.getItemForID("bookmarkpreviews@mozdev.org");
- var currentVersion = addon.version;
- var lastVersion = PreviewService.prefs.getCharPref("currentVersion");
- if (lastVersion == "none") {
- PreviewService.prefs.setCharPref("currentVersion", currentVersion);
- PreviewService.showFirstRunDialog();
- } else if (versionChecker.compare(currentVersion,lastVersion) > 0) {
- PreviewService.prefs.setCharPref("currentVersion", currentVersion);
- /* any upgrade code goes here */
- }
- },
- onUnload: function() {
- gBrowser.removeEventListener('load',PreviewService.onPageLoad,true);
- if (!PreviewService.isFF3)
- gBrowser.removeProgressListener(PreviewService.listener);
- PreviewService.bookmarks.unload();
- },
- onPageLoad : function(event){
- var doc = event.originalTarget;
- if (doc instanceof Components.interfaces.nsIDOMDocument) {
- if (doc.defaultView.frameElement) {
- // Frame within a tab was loaded. doc should be the root document of
- // the frameset.
- // Find the root document:
- while (doc.defaultView.frameElement) {
- doc=doc.defaultView.frameElement.ownerDocument;
- }
- }
- if (doc && doc.URL){
- var uri = null;
- try{/* catch malformed uri errors */
- uri = makeURI(doc.URL);
- }catch(e){}
- if (!uri) return;
- var browser = gBrowser.getBrowserForDocument(doc);
- if (browser)
- PreviewService.onURILoad(uri, browser);
- }
- }
- },
- onURILoad : function(uri,browser){
- var isBookmarked = uri.equals(PreviewService._lastCheck.uri)?PreviewService._lastCheck.isBookmarked:PreviewService.bookmarks.isBookmarked(uri);
- //dump("onuriload: "+isBookmarked+"\n");
- if (isBookmarked && PreviewService.shouldCreatePreview(uri)){
- if (PreviewService.timeouts[uri.spec]!=null)
- clearTimeout(PreviewService.timeouts[uri.spec]);
- /* Just to give it time to load a little more... */
- PreviewService.timeouts[uri.spec]=setTimeout(function(){
- PreviewService.timeouts[uri.spec]=null;
- PreviewService.createPreviewFromBrowser(browser,uri);
- },1500);
- }
- PreviewService._lastCheck.uri = uri;
- PreviewService._lastCheck.isBookmarked = isBookmarked;
- },
- shouldCreatePreview : function(uri){
- if (!uri || !uri.scheme) return false;
- var allowHTTPS = this.prefs.getBoolPref("createForHTTPS");
- var schemes = ["http","chrome"];
- if (allowHTTPS) schemes.push("https");
- return schemes.indexOf(uri.scheme)>-1;
- },
- getBrowserForURI : function(uri){
- var numTabs = gBrowser.tabContainer.childNodes.length;
- for(var index=0; index<numTabs; index++) {
- var currentBrowser = gBrowser.getBrowserAtIndex(index);
- if (uri.equals(currentBrowser.currentURI)) {
- return currentBrowser;
- }
- }
- return null;
- },
- bookmarkAdded : function(uri){
- var currentBrowser = this.getBrowserForURI(uri);
- if (currentBrowser)
- this.createPreviewFromBrowser(currentBrowser);
- },
- createPreviewFromBrowser : function(browser, uri, aWidth, aHeight){
- uri = uri ? uri : browser.currentURI;
- //dump("creatpreviewfrombrowser: "+uri.spec+"\n");
- var win=browser.contentWindow;
- if (!win)/*the window may have closed before the timeout*/
- return;
- aWidth = (aWidth && aWidth!=0)?aWidth:win.innerWidth;
- aHeight = (aHeight && aHeight!=0)?aHeight:win.innerHeight;
- var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
- var scale=this.PREVIEW_WIDTH/(aWidth);
- canvas.height = Math.floor(scale*(aHeight));
- canvas.width = this.PREVIEW_WIDTH;
- var ctx = canvas.getContext("2d");
- ctx.save();
- ctx.scale(scale, scale);
- ctx.drawWindow(win, 0, 0, aWidth, aHeight,"rgb(255,255,255)");
- ctx.restore();
- var data = canvas.toDataURL("image/jpeg", "");
- if(data && data != "") {
- try {
- this.bookmarks.savePreview(data,uri);
- this.sendUpdateNotification(uri);
- } catch(e) {
- Components.utils.reportError("Bookmarks Previews: Error saving bookmark image for uri\n"+uri.spec+"\nError: "+e+"\n");
- }
- }
- },
- sendUpdateNotification : function(uri){
- /* When notifying the observers right away, the observers still seem to think
- that the file doesn't exist. */
- //dump("send update notification\n");
- setTimeout(function(){
- Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService)
- .notifyObservers(uri, "bookmarkpreviews:preview-updated", null);
- },0);
- },
- showFirstRunDialog : function(){
- var self = this;
- var strbundleService = Components.classes ["@mozilla.org/intl/stringbundle;1"]
- .getService(Components.interfaces.nsIStringBundleService);
- this.bundle = strbundleService.createBundle("chrome://bookmarkpreviews/locale/strings.properties");
- var dialogQ = this.bundle.GetStringFromName("firstrundialog");
- var dialogTitle = this.bundle.GetStringFromName("firstrundialogtitle");
- /* Give it some time for the browser to actually load */
- setTimeout(function(){
- var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService);
- var result = prompts.confirm(window, dialogTitle, dialogQ);
- if (result){
- self.generateAllPreviews();
- } else
- delete this.bundle;
- },2000);
- },
- generateAllPreviews : function(){
- if (!this.generator || this.generator.status == "complete"){
- this.generator = new PreviewGenerator();
- this.generator.generateAllPreviews();
- } else {
- /* still generating */
- }
- }
- }
- function PreviewGenerator(){}
- PreviewGenerator.prototype = {
- LOAD_TIMEOUT : 1000 * 60,
- status: null,
- generateAllPreviews : function(){
- this.allBookmarks = PreviewService.bookmarks.getAllBookmarks();
- if (!this.allBookmarks || this.allBookmarks.length==0){
- this.allBookmarks = null;
- return;
- }
- if (!this.bundle){
- var strbundleService = Components.classes ["@mozilla.org/intl/stringbundle;1"]
- .getService(Components.interfaces.nsIStringBundleService);
- this.bundle = strbundleService.createBundle("chrome://bookmarkpreviews/locale/strings.properties");
- }
- this.status = "loading";
- this.curPreview = -1;
- this.browser = document.getElementById("bookmarkpreviews-browser");
- if (!this.browser){
- this.browser = document.createElement("browser");
- this.browser.setAttribute("id","bookmarkpreviews-browser");
- this.browser.setAttribute("width",1);
- this.browser.setAttribute("height",1);
- this.browser.setAttribute("type","content");
- this.browser = document.documentElement.appendChild(this.browser);
- }
- this.browser.hidden = false;
-
- /* The canvas can't save flash/java so don't waste time loading it*/
- this.browser.docShell.allowPlugins = false;
- /* So it doesn't launch any windows as its working in the background*/
- this.browser.docShell.allowJavascript = false;
- /* don't throw up password dialogs */
- this.browser.docShell.allowAuth = false;
- this.browser.stop();
-
- var listener = new BookmarkPreviewsProgressListener();
- listener.getBrowser = function BP_GetBrowser(uri){
- return document.getElementById("bookmarkpreviews-browser");
- }
- listener.onURILoad = this.onPreviewLoad;
- listener.surpressDialogs = !PreviewService.isFF3;
- this.browser.addProgressListener(listener,Components.interfaces.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
- this.previewGenListener = listener;
- this.browser.addEventListener("load",this,true);
- this.loadNextBookmark();
- },
- onPreviewLoad : function(uri){
- var self = PreviewService.generator;
- if (self.status == "loading" && uri.equals(self.allBookmarks[self.curPreview])){
- if (self.generateTimeout!=null){
- clearTimeout(self.generateTimeout);
- }
- self.generateTimeout=setTimeout(function(){
- try{
- if (self.status == "loading")
- self.generatePreview(uri,self.browser);
- }catch(e){
- dump("previewload: error: "+e);
- }
- },1500);
- }
- },
- generatePreview : function(uri){
- this.generateTimeout = null;
- var browser = this.browser;
- if (!browser || !browser.stop){
- return;
- }
- if (browser){
- browser.stop();
- PreviewService.createPreviewFromBrowser(browser,uri,gBrowser.boxObject.width,gBrowser.boxObject.height);
- }
- this.loadNextBookmark();
- },
- handleEvent : function(event){
- if (event.type == "load")
- this.onPageLoad(event);
- },
- onPageLoad : function(event){
- var doc = event.originalTarget;
- if (doc instanceof Components.interfaces.nsIDOMDocument) {
- if (doc.defaultView.frameElement) {
- // Frame within a tab was loaded. doc should be the root document of
- // the frameset.
- // Find the root document:
- while (doc.defaultView.frameElement) {
- doc=doc.defaultView.frameElement.ownerDocument;
- }
- }
- var uri = null;
- try{
- uri = makeURI(doc.URL);
- }catch(e){}
- if (!uri) return;
- this.onPreviewLoad(uri);
- }
- },
- loadNextBookmark : function(){
- var uri = null;
- while (!uri && this.curPreview+1<this.allBookmarks.length){
- this.curPreview++;
- uri = this.allBookmarks[this.curPreview];
- if (!uri || !(uri.scheme=="http" || uri.scheme=="https") ||
- !PreviewService.shouldCreatePreview(uri) ||
- PreviewService.bookmarks.hasPreview(uri.spec)){
- uri = null;
- }
- }
- var self = this;
- if (!uri){
- function generatetimedout(){
- try{
- if (self.status!="complete")
- self.generatePreviewsComplete();
- }catch(e){dump("ctimedoute: "+e+"\n");}
- }
- self.generateTimeout = setTimeout(generatetimedout,2000);
- }
- else{
- var statusTextFld = document.getElementById("statusbar-display");
- var statustext = this.bundle.GetStringFromName("creatingpreview.statustext");
- statusTextFld.label = statustext.replace("$1",(this.curPreview+1)).replace("$2",this.allBookmarks.length).replace("$3",uri.spec)
- var flags = Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY;
- try{
- this.browser.loadURIWithFlags(uri.spec,flags,null,null);
- function timedout(){
- try{
- self.generatePreview(uri);
- }catch(e){dump("timedoute: "+e+"\n");}
- }
- self.generateTimeout = setTimeout(timedout,this.LOAD_TIMEOUT);
- }catch(e){
- dump("BPError: "+e);
- this.loadNextBookmark();
- }
- }
- },
- generatePreviewsComplete : function(){
- this.status = "complete";
- alert(this.bundle.GetStringFromName("previewsgenerated"));
- this.browser.removeProgressListener(this.previewGenListener);
- this.browser.removeEventListener("load",this,true);
- //this.browser = this.browser.parentNode.removeChild(this.browser);
- this.browser.hidden = true;
- this.previewGenListener = null;
- this.allBookmarks = null;
- this.browser = null;
- this.curPreview = null;
- this.bundle = null;
- }
- }
- function BookmarkPreviewsProgressListener(){
-
- }
- BookmarkPreviewsProgressListener.prototype = {
- onURILoad : null,
- getBrowser : null,
- surpressDialogs : false,
- QueryInterface: function(aIID) {
- if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
- aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
- aIID.equals(Components.interfaces.nsISupports))
- return this;
- throw Components.results.NS_NOINTERFACE;
- },
- onStateChange: function(aProgress, aRequest, aFlag, aStatus) {
- if (aFlag & STATE_START &&
- aRequest && aRequest instanceof Ci.nsIChannel &&
- this.surpressDialogs == true
- ){
- aRequest.notificationCallbacks = new BookmarkPreviewsListener();
- }
- if(aFlag & STATE_STOP){
- if (aRequest instanceof Components.interfaces.nsIChannel){
- var chan = aRequest.QueryInterface(Components.interfaces.nsIChannel);
- if (!chan.URI.equals(chan.originalURI)){
- var browser = this.getBrowser(chan.URI);
- if (browser)
- this.onURILoad(chan.originalURI,browser);
- }
- }
- }
- return 0;
- },
- onLocationChange: function(aProgress, aRequest, aURI){},
- onProgressChange: function() {return 0;},
- onStatusChange: function() {return 0;},
- onSecurityChange: function() {return 0;},
- onLinkIconAvailable: function() {return 0;}
- }
- /*
- Surpress cert dialogs and other errors when loading sites in the background
- */
- function BookmarkPreviewsListener(callback){
- this.callback = callback;
- }
- BookmarkPreviewsListener.prototype = {
- /* Whether to load the site or not if there is an error */
- load : false,
- // nsIInterfaceRequestor
- getInterface: function BKMKP_load_GI(aIID) {
- return this.QueryInterface(aIID);
- },
- /* nsIBadCertListener2
- return true to suppress the error message
- */
- notifyCertProblem: function BKMKP_certProblem(socketInfo, status, targetSite) {
- dump("bad cert - notify cert problem\n");
- return true;
- },
- /* nsIBadCertListener
- return true to load the page, false to stop loading
- */
- confirmUnknownIssuer: function BKMKP_load_CUI(aSocketInfo, aCert,
- aCertAddType) {
- dump("bad cert issuer\n");
- dump("cert url: "+(PreviewService.generator.allBookmarks[PreviewService.generator.curPreview].spec)+"\n");
- return this.load;
- },
- confirmMismatchDomain: function BKMKP_load_CMD(aSocketInfo, aTargetURL,
- aCert) {
- dump("bad cert - mismatch domain\n");
- dump("cert url: "+(PreviewService.generator.allBookmarks[PreviewService.generator.curPreview].spec)+"\n");
- return this.load;
- },
- confirmCertExpired: function BKMKP_load_CCE(aSocketInfo, aCert) {
- dump("notifyCertProblem - certexpired\n");
- dump("cert url: "+(PreviewService.generator.allBookmarks[PreviewService.generator.curPreview].spec)+"\n");
- return this.load;
- },
- notifyCrlNextupdate: function BKMKP_load_NCN(aSocketInfo, aTargetURL, aCert) {
- dump("bad cert - crlnextupdate\n");
- dump("cert url: "+(PreviewService.generator.allBookmarks[PreviewService.generator.curPreview].spec)+"\n");
- },
- /* nsISSLErrorListener
- return true to suppress the error
- */
- notifySSLError: function BKMKP_SSLError(socketInfo, error, targetSite) {
- dump("ssl error\n")
- dump("site url: "+(PreviewService.generator.allBookmarks[PreviewService.generator.curPreview].spec)+"\n");
- return true;
- },
- /* nsIAuthPrompt
- return false to cancel
- */
- prompt : function ( dialogTitle, text, passwordRealm, savePassword, defaultText, result){
- dump("prompt site url: "+(PreviewService.generator.allBookmarks[PreviewService.generator.curPreview].spec)+"\n");
- return false;
- },
- // nsIAuthPrompt
- promptUsernameAndPassword : function( dialogTitle, text, passwordRealm, savePassword, user, pwd){
- dump("promptUAP site url: "+(PreviewService.generator.allBookmarks[PreviewService.generator.curPreview].spec)+"\n");
- return false;
- },
- // nsIAuthPrompt
- promptPassword : function( dialogTitle, text, passwordRealm, savePassword, pwd){
- dump("promptP site url: "+(PreviewService.generator.allBookmarks[PreviewService.generator.curPreview].spec)+"\n");
- return false;
- },
- QueryInterface: function BKMKP_loadQI(aIID) {
- if (aIID.equals(Ci.nsISupports) ||
- aIID.equals(Ci.nsIInterfaceRequestor) ||
- aIID.equals(Ci.nsIBadCertListener) || //FF2
- aIID.equals(Ci.nsIBadCertListener2) || //FF3
- aIID.equals(Ci.nsISSLErrorListener) ||
- aIID.equals(Ci.nsIAuthPrompt) ||
- false){
- return this;
- }
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
- }
- function PreviewServiceFF3(){
- this.dir = Components.classes["@mozilla.org/file/directory_service;1"]
- .getService(Components.interfaces.nsIProperties)
- .get("ProfD", Components.interfaces.nsIFile);
- this.dir.append("bookmarkpreviews");
- if (!this.dir.exists())
- this.dir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE,0777);
-
- this.register();
- }
- PreviewServiceFF3.prototype = {
- toString : function(){return "Firefox 3 Preview Service";},
- txnlistener : null,
- dir : null,
- unload : function(){
- this.unregister();
- },
- register : function(){
- PlacesUtils.bookmarks.addObserver(this.observer, false);
- },
- unregister : function(){
- PlacesUtils.bookmarks.removeObserver(this.observer,false);
- },
- isBookmarked : function(uri){
- return PlacesUtils.bookmarks.getBookmarkedURIFor(uri)!=null;
- },
- hasPreview : function(aUrl){
- return PreviewServiceUtils.getPreviewFile(aUrl,this.dir).exists();
- },
- savePreview : function(data,uri){
- var file = PreviewServiceUtils.getPreviewFile(uri.spec,this.dir);
- var io = Components.classes["@mozilla.org/network/io-service;1"]
- .getService(Components.interfaces.nsIIOService);
- var source = io.newURI(data, "UTF8", null);
- var target = io.newFileURI(file)
- // prepare to save the data
- var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
- .createInstance(Components.interfaces.nsIWebBrowserPersist);
- persist.persistFlags = Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
- persist.persistFlags |= Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
-
- persist.saveURI(source, null, null, null, null, file);
- },
- /* generate all previews... */
- getAllBookmarks : function(root,bkmks){
- if (!root){
- var roots = Application.bookmarks;
- root = roots.children?roots:{children: [roots.menu,roots.toolbar,roots.unfiled]};
- bkmks = [];
- }
- var ls = Cc["@mozilla.org/browser/livemark-service;2"]
- .getService(Ci.nsILivemarkService);
- root.children.forEach(function(item,idx){
- if (item.type=="bookmark"){
- bkmks.push(item.uri);
- }
- else if (item.type=="folder" && !ls.isLivemark(item.id)){
- this.getAllBookmarks(item,bkmks);
- }
- },this);
- return bkmks;
- },
-
- observer : {
- get mOuter(){return PreviewService.bookmarks;},
- changed: {id: null, uri: null},
- /* nsINavBookmarkObserver */
- onBeginUpdateBatch : function(){},
- onEndUpdateBatch : function(){},
- onItemAdded : function(aItemId, aFolder, aIndex){
- var uri = PlacesUtils.bookmarks.getBookmarkURI(aItemId);
- PreviewService.bookmarkAdded(uri);
- },
- /*
- Since this is method is called after a bookmark is already removed we can't
- get the bookmark's url. To work around this we record the uri in the itemchange
- method which is called before the bookmark is removed
- */
- onItemRemoved : function(aItemId, aFolder, aIndex){
- if (aItemId == this.changed.id){
- var uri = this.changed.uri;
- if (!this.mOuter.isBookmarked(uri)){
- var file = PreviewServiceUtils.getPreviewFile(uri.spec,this.mOuter.dir);
- if (file.exists())
- file.remove(false);
- }
- }
- },
- onItemChanged : function(aBookmarkId, aProperty, aIsAnnotationProperty, aValue){
- //dump("changed bookmark - "+aBookmarkId+" - prop: "+aProperty+" ann: "+aIsAnnotationProperty+" - value: "+aValue+"\n");
- if (["title","favicon","tags","cleartime","keyword","bookmarkProperties/description",
- "bookmarkProperties/loadInSidebar"].indexOf(aProperty)>-1)
- return;
- else if (aProperty == "uri"){
- //remove old... add new
- //but we can't remove the old since it's already been removed
- //aValue == new url and getting the bookmarked uri == the new url
- try{/* catch malformed uri error */
- PreviewService.bookmarkAdded(makeURI(aValue));
- }catch(e){}
- }
- else{
- this.changed.id = aBookmarkId;
- this.changed.uri = PlacesUtils.bookmarks.getBookmarkURI(aBookmarkId);
- }
- },
- onItemVisited : function(aBookmarkId, aVisitID, time){},
- onItemMoved : function(aItemId, aOldParent, aOldIndex, aNewParent, aNewIndex){}
- }
- }
- function PreviewServiceFF2(){
- initServices();
- initBMService();
- this.bmsvc = BMSVC;
- this.dir = Components.classes["@mozilla.org/file/directory_service;1"]
- .getService(Components.interfaces.nsIProperties)
- .get("ProfD", Components.interfaces.nsIFile);
- this.dir.append("bookmarkpreviews");
- if (!this.dir.exists())
- this.dir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE,0777);
-
- this.register();
- }
- PreviewServiceFF2.prototype = {
- txnlistener : null,
- toString : function(){return "Firefox 3 Preview Service";},
- unload : function(){
- this.unregister();
- },
- register : function(){
- var bkmkTxnSvc = Components.classes["@mozilla.org/bookmarks/transactionmanager;1"]
- .getService(Components.interfaces.nsIBookmarkTransactionManager);
- this.txnlistener = new BookmarkPreviewsTransactionListener(this);
- bkmkTxnSvc.transactionManager.AddListener(this.txnlistener);
- },
- unregister : function(){
- var bkmkTxnSvc = Components.classes["@mozilla.org/bookmarks/transactionmanager;1"]
- .getService(Components.interfaces.nsIBookmarkTransactionManager);
- bkmkTxnSvc.transactionManager.RemoveListener(this.txnlistener);
- },
- isBookmarked : function(uri){
- var NC = "http://home.netscape.com/NC-rdf#";
- var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
- var BMDS = RDF.GetDataSource("rdf:bookmarks");
- var urlArc = RDF.GetResource(NC+"URL");
- var elements = BMDS.GetAllResources();
- while (elements.hasMoreElements()){
- var ele = elements.getNext();
- if(BMDS.hasArcOut(ele, urlArc)){
- var target = BMDS.GetTarget(ele, urlArc, true);
- var value = target.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
- if(value == uri.spec){
- ele.QueryInterface(Components.interfaces.nsIRDFResource);
- var resParent= BMSVC.getParent(ele);
- if (resParent){
- var name = BookmarksUtils.getProperty(resParent, "http://home.netscape.com/NC-rdf#Name");
- if (name!=""){
- return true;
- }
- }
- }
- }
- }
- return false;
- },
- hasPreview : function(aUrl){
- return PreviewServiceUtils.getPreviewFile(aUrl,this.dir).exists();
- },
- savePreview : function(data,uri,aArg){
- var file = PreviewServiceUtils.getPreviewFile(uri.spec,this.dir);
- var io = Components.classes["@mozilla.org/network/io-service;1"]
- .getService(Components.interfaces.nsIIOService);
- var source = io.newURI(data, "UTF8", null);
- var target = io.newFileURI(file);
- if (file.exists())
- file.remove(true);
- // prepare to save the data
- var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
- .createInstance(Components.interfaces.nsIWebBrowserPersist);
- persist.persistFlags = Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
- persist.persistFlags |= Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
-
- persist.saveURI(source, null, null, null, null, file);
- },
- removePreview : function(url){
- try{/* catch malformed uri and file io errors */
- if (!this.isBookmarked(makeURI(url))){
- var file = PreviewServiceUtils.getPreviewFile(url,this.dir);
- if (file.exists())
- file.remove(false);
- }
- }catch(e){}
- },
- observeTransaction : function(aState, aTxn, aDo){
- if (!aTxn) return;
- aTxn = aTxn.wrappedJSObject;
- //dump("observe transaction: "+aTxn.type+" action: "+aTxn.action+"\n");
- if ((aTxn.type!="insert" && aTxn.type!="remove") || aTxn.action == "move") return;
- var type = aTxn.type;
- var item = aTxn.item;
- var isContainer = null;
- function resourceIsContainer(aResource){
- var type = BookmarksUtils.resolveType(aResource);
- return type.indexOf("Folder")>-1 ||
- type == "Livemark" ||
- false;
- }
- /*
- When removing a bookmark folder the type is originally 'Folder' in the
- 'will' stage, but after it is removed the type is 'ImmutableBookmark'. We
- need to check what type it is before the item is actually removed.
- */
- if (aTxn.type=="remove" && aDo){
- if (aState == "will"){
- this._transactionItemType = resourceIsContainer(item);
- return;
- } else {
- isContainer = this._transactionItemType;
- delete this._transactionItemType;
- }
- } else
- isContainer = resourceIsContainer(item);//RDFCU.IsContainer(BMDS, RDF.GetResource(item));
- if (aState=="will") return;
-
- var urls = [];
- if (isContainer){
- try{
- var propArray = [];
- BookmarksUtils.getAllChildren(item, propArray);
- propArray.forEach(function(props,idx1){
- var prop = props[1];
- if (prop)
- urls.push(prop.Value);
- });
- }
- catch(e){}
- }
- var itemURL = null;
- itemURL = aTxn.removedProp[1];
- if (itemURL)
- urls.push(itemURL.Value);
- else{
- itemURL = BookmarksUtils.getProperty(aTxn.item,aTxn.Properties[1].Value);
- if (itemURL)
- urls.push(itemURL);
- }
- urls.forEach(function(url,idx){
- try{/* catch malformed uri errors */
- if (((type == "insert" && aDo) || (type == "remove" && !aDo)) && url){
- PreviewService.bookmarkAdded(makeURI(url));
- }
- else if (((type == "remove" && aDo) || (type == "insert" && !aDo)) && url){
- this.removePreview(url);
- }
- }catch(e){}
- },this);
- },
- /* Used for generating all previews */
- getAllBookmarks : function(){
- var children = [], all = [];
- BookmarksUtils.getAllChildren(RDF.GetResource("NC:BookmarksRoot"),children);
- for (var i = 0; i < children.length; i++){
- try{
- if (children[i][1] && children[i][1].Value!=null){
- all.push(makeURI(children[i][1].Value));
- }
- }catch(e){dump(e+"\n");}
- }
- return all;
- }
- }
- function BookmarkPreviewsTransactionListener(parent){
- this.parent = parent;
- }
- BookmarkPreviewsTransactionListener.prototype = {
- willDo: function (aTxmgr, aTxn) {
- this.parent.observeTransaction("will", aTxn, true);
- },
- didDo : function (aTxmgr, aTxn) {
- this.parent.observeTransaction("did", aTxn, true);
- },
- willUndo: function (aTxmgr, aTxn) {
- this.parent.observeTransaction("will", aTxn, true);
- },
- didUndo : function (aTxmgr, aTxn) {
- this.parent.observeTransaction("did", aTxn, false);
- },
- willRedo: function (aTxmgr, aTxn) {
- this.parent.observeTransaction("will", aTxn, true);
- },
- didRedo : function (aTxmgr, aTxn) {
- this.parent.observeTransaction("did", aTxn, true);
- },
- didMerge : function (aTxmgr, aTxn) {},
- didBeginBatch : function (aTxmgr, aTxn) {},
- didEndBatch : function (aTxmgr, aTxn) {
- this.parent.observeTransaction("did", aTxn, true);
- },
- willMerge : function (aTxmgr, aTxn) {},
- willBeginBatch : function (aTxmgr, aTxn) {},
- willEndBatch : function (aTxmgr, aTxn) {}
- }
- window.addEventListener('load',function(e) { PreviewService.onLoad(e); },false);
- window.addEventListener('unload',function(e) { PreviewService.onUnload(e); },false);
-